﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using NetCoreServer;
using DidaManager.Log;

namespace DidaManager.Native.RemoteTransmission
{
    public class TransTcpServer : TcpServer
    {
        private List<MyTcpSession> sessions = new List<MyTcpSession>();
        public delegate void DataReceivedHandler(byte[] buffer, long offset, long size);
        public delegate void DataSentHandler(string data);
        public delegate void ConnectStatusHandler(string data);
        public event DataReceivedHandler? DataReceived;
        public event DataSentHandler? DataSent;
        public event ConnectStatusHandler? ConnectStatus;

        public TransTcpServer(string address, int port) : base(address, port) { }

        protected override TcpSession CreateSession() { return new MyTcpSession(this); }

        protected override void OnError(SocketError error) { LogManager.Error($"Error: {error}"); }

        public void SendData(string data)
        {
            bool bRet = RspTransWebsocketData.CheckForCodeAndMessage(data);
            if(bRet || !IsStarted)// 是返回应答状态，不是数据
            {
                LogManager.Warn("tcpserver recv not valid data: " + data);
                return;
            }
            DirectData? temp = DirectData.FromJson(data);
            if (temp == null) return;
            byte[] buffer = Convert.FromBase64String(temp.Data);
            if (temp.DataLen != buffer.Length)
            {
                Array.Clear(buffer, 0, buffer.Length);
                buffer = Convert.FromHexString(temp.Data);
            }
            foreach (var session in sessions)
            {
                string hexString = BitConverter.ToString(buffer, 0, buffer.Length).Replace("-", " ");
                LogManager.Debug($"TCP SendData Length: ", buffer.Length.ToString());
                LogManager.Debug($"TCP Send Hex Data : " + hexString);

                session.SendAsync(buffer, 0, buffer.Length);
                DataSent?.Invoke(data);
            }
        }

        public void AddSession(MyTcpSession session)
        {
            sessions.Add(session);
        }

        public void RemoveSession(MyTcpSession session)
        {
            sessions.Remove(session);
        }

        public bool HasSession()
        {
            return sessions.Count>0;
        }

        public class MyTcpSession : TcpSession
        {
            private List<BufferObject> bufferObjects;
            private bool bConnected = false;
            public MyTcpSession(TcpServer server) : base(server)
            {
                bConnected = false;
                bufferObjects = new List<BufferObject>();
            }

            public void AddBuffer(int bufferSize, byte[] data, int offset, int size)
            {
                BufferObject buffer = new BufferObject(bufferSize,offset);
                buffer.BufferData(data, offset, size);
                bufferObjects.Add(buffer);
            }

            public (byte[], long,long) GetAndRemoveFirstBuffer()
            {
                if (bufferObjects.Count > 0)
                {
                    BufferObject firstBuffer = bufferObjects[0];
                    bufferObjects.RemoveAt(0);
                    Console.WriteLine("First buffer removed successfully");
                    return (firstBuffer.GetBuffer(), firstBuffer.GetSize(),firstBuffer.GetOffset());
                }
                else
                {
                    Console.WriteLine("No buffers available");
                    return (new byte[1], 0, 0);
                }
            }

            protected override void OnConnected()
            {
                LogManager.Debug($"TCP session connected");
                ((TransTcpServer)Server).AddSession(this);
                ((TransTcpServer)Server).ConnectStatus?.Invoke("connect");
                bConnected = true;

                //把缓冲的数据发送出去
                while (bufferObjects.Count > 0)
                {
                    var (buffer, size,offset) = GetAndRemoveFirstBuffer();
                    if (buffer != null)
                    {
                        OnReceived(buffer, offset, size);
                    }
                }
            }

            protected override void OnDisconnected()
            {
                bConnected = false;
                LogManager.Debug($"TCP session disconnected");
                ((TransTcpServer)Server).RemoveSession(this);
                ((TransTcpServer)Server).ConnectStatus?.Invoke("disconnect");
            }

            protected override void OnReceived(byte[] buffer, long offset, long size)
            {
                if(!bConnected)
                {
                    AddBuffer((int)size,buffer, (int)offset, (int)size);
                    return;
                }
                string hexString = BitConverter.ToString(buffer, (int)offset, (int)size).Replace("-", " ");
                LogManager.Debug("TCP Recv  Length: " + size);
                LogManager.Debug("TCP Recv  Hex Data : " + hexString);

                ((TransTcpServer)Server).DataReceived?.Invoke(buffer,offset,size);
            }
        }
    }

}
